﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;


namespace IcyTowerMobile
{
	/// <summary>
	/// Class representing a tower platform.
	/// </summary>
	public class Platform
	{
		/// <summary>
		/// Minimum number of middle parts in a platform.
		/// </summary>
		private const int NR_MIDDLE_PARTS_MIN = 3;
		/// <summary>
		/// Maximum number of middle parts in a platform.
		/// </summary>
		private const int NR_MIDDLE_PARTS_MAX = 10;

		/// <summary>
		/// Static instance of a random generator. Used for generating
		/// random x positions and random platform widths.
		/// </summary>
		private static Random platformSeed = new Random((int)DateTime.Now.Ticks);

		private Texture2D leftTexture;
		private Texture2D middleTexture;
		private Texture2D rightTexture;
		private int nOfMiddleParts;
		private Vector2 position;
		private int screenHeight;

		private int minXPos;
		private int maxXPos;
		private Rectangle boundingBox;
		private bool isIntersected;
		private int scoreStartValue;

		private int currentSpeed;
		private bool playerIsHighEnough;

		public bool PlayerIsHighEnough
		{
			get { return playerIsHighEnough; }
		}

		public int Speed
		{
			get { return currentSpeed; }
		}

		public int Height
		{
			get { return Math.Max(Math.Max(leftTexture.Height, rightTexture.Height), middleTexture.Height); }
		}

		public int Width
		{
			get { return leftTexture.Width + middleTexture.Width * nOfMiddleParts + rightTexture.Width; }
		}

		public bool IsIntersected
		{
			get { return isIntersected; }
			set { isIntersected = value; }
		}

		public int Value
		{
			get { return scoreStartValue; }
		}

		public Vector2 Position
		{
			get { return position; }
		}

		public Rectangle BoundingBox
		{
			get { return boundingBox; }
		}

		/// <summary>
		/// Allows the game component to perform any initialization it needs to before starting
		/// to run.  This is where it can query for any required services and load content.
		/// </summary>
		public void Initialize(Texture2D leftTexture, Texture2D middleTexture, Texture2D rightTexture, int yPos, int screenHeight, int minXPos, int maxXPos, int scoreStartValue, int speed)
		{
			this.leftTexture = leftTexture;
			this.middleTexture = middleTexture;
			this.rightTexture = rightTexture;

			this.nOfMiddleParts = platformSeed.Next(NR_MIDDLE_PARTS_MIN, NR_MIDDLE_PARTS_MAX);
			this.position = new Vector2();
			this.position.Y = yPos;
			this.position.X = platformSeed.Next(minXPos, maxXPos - Width);

			this.currentSpeed = speed;
			this.minXPos = minXPos;
			this.maxXPos = maxXPos;
			this.screenHeight = screenHeight;
			this.isIntersected = false;
			this.scoreStartValue = scoreStartValue;
			this.boundingBox = new Rectangle((int)position.X, (int)position.Y, Width, Height);
		}

		/// <summary>
		/// Allows the game component to update itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		public void Update(GameTime gameTime, int movement, bool playerIsHighEnough)
		{
			position.Y += movement;

			if (playerIsHighEnough)
			{
				// apply speed to platform if user has reached a certain height
				this.playerIsHighEnough = playerIsHighEnough;
				position.Y += currentSpeed;
			}


			// Check if the texture is out of view then position it to the start of the screen
			if (position.Y >= screenHeight)
			{
				// generate new random number for middle parts
				nOfMiddleParts = platformSeed.Next(NR_MIDDLE_PARTS_MIN, NR_MIDDLE_PARTS_MAX);
				position.Y = -(Height - movement);
				// generate new x position
				position.X = platformSeed.Next(minXPos, maxXPos - Width);

				// increment score value of this platform
				scoreStartValue += GameplayScreen.NR_PLATFORMS_PER_SCREEN;
			}

			if (scoreStartValue % 100 == 0)
			{
				// platform is a hundredth, make it whole screen width
				position.X = minXPos;
				boundingBox = new Rectangle((int)position.X, (int)position.Y, maxXPos - minXPos, Height);
			}
			else
			{
				boundingBox = new Rectangle((int)position.X, (int)position.Y, Width, Height);
			}
		}

		public void Draw(SpriteBatch spriteBatch)
		{
			Vector2 drawingPosition = position;

			if (scoreStartValue % 100 == 0)
			{
				// platform is a hundredth, make it whole screen width
				for (int i = 0; i < 480; i = i + middleTexture.Width)
				{
					spriteBatch.Draw(middleTexture, new Vector2(i, position.Y), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
				}
			}
			else
			{
				// draw left part of platform
				spriteBatch.Draw(leftTexture, drawingPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
				drawingPosition.X += leftTexture.Width;

				// draw middle parts of platform
				for (int i = 0; i < nOfMiddleParts; i++)
				{
					spriteBatch.Draw(middleTexture, drawingPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
					drawingPosition.X += middleTexture.Width;
				}
				// draw right parts of platform
				spriteBatch.Draw(rightTexture, drawingPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
			}
		}

		/// <summary>
		/// Increases game speed for this component by 1.
		/// </summary>
		public void IncreaseSpeed()
		{
			currentSpeed += 1;
		}
	}
}
